//
//  DMAdjustManager.m
//  DualMediationSDK
//
//  Created by YeJary on 2025/8/5.
//

#import "DMAdjustManager.h"
#import "DMAdjustAttributionInfo.h"
#import "../../Utils/JSON/DMConfigReader.h"
#import "../../Utils/Encryption/IMEncryptUtils.h"
#import "../../Utils/Device/IMKeychainUUIDManager.h"
#import "../../Utils/Logger/IMLogUtils.h"
#import <AdjustSdk/AdjustSdk.h>
#import <ThinkingSDK/ThinkingSDK.h>

#ifdef DEBUG//调试状态，打开LOG功能
#define environment1 ADJEnvironmentSandbox
#else//发布状态，关闭LOG功能
#define environment1 ADJEnvironmentProduction
#endif

// 归因回调超时时间（秒）
static const NSTimeInterval kAttributionTimeoutInterval = 8.0;

@interface DMAdjustManager()<AdjustDelegate> {
    // 兼容旧属性的内部存储
    void(^_adjustCallBackBlcok)(BOOL isSuccess);
    NSString *_adjustCampaign;
    NSString *_adjustCreative;
}

// 新增属性
@property (nonatomic, strong) DMAdjustAttributionInfo *currentAttribution;
@property (nonatomic, copy) void(^attributionCallback)(BOOL isSuccess);
@property (nonatomic, strong) NSTimer *attributionTimeoutTimer;
@property (nonatomic, assign) BOOL isInitialized;
@property (nonatomic, strong) NSString *appToken;

@end

@implementation DMAdjustManager

static DMAdjustManager *_sharedManager = nil;

#pragma mark - Singleton

+ (instancetype)sharedManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedManager = [[self alloc] init];
    });
    return _sharedManager;
}

+ (instancetype)shareAdjustManager {
    [IMLogUtils warning:IMLogTagAd format:@"[Adjust] shareAdjustManager is deprecated, use sharedManager instead"];
    return [self sharedManager];
}

- (instancetype)init {
    self = [super init];
    if (self) {
        _isInitialized = NO;
        [IMLogUtils info:IMLogTagAd format:@"[Adjust] DMAdjustManager initialized"];
    }
    return self;
}

#pragma mark - Configuration

- (void)configureWithAppToken:(NSString *)appToken {
    if (!appToken || appToken.length == 0) {
        [IMLogUtils error:IMLogTagAd format:@"[Adjust] App token is required for configuration"];
        return;
    }
    
    if (_isInitialized) {
        [IMLogUtils warning:IMLogTagAd format:@"[Adjust] Already initialized, skipping configuration"];
        return;
    }
    
    _appToken = appToken;
    
    ADJConfig *adjustConfig = [[ADJConfig alloc] initWithAppToken:appToken
                                                      environment:environment1];
    [adjustConfig setLogLevel:ADJLogLevelVerbose];
    [adjustConfig setAttConsentWaitingInterval:15];
    adjustConfig.delegate = self;
    [Adjust initSdk:adjustConfig];
    _isInitialized = YES;
    
    [IMLogUtils info:IMLogTagAd format:@"[Adjust] Configured with app token: %@", appToken];
    
    NSString *countryCode = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];

    [Adjust addGlobalPartnerParameter:[IMEncryptUtils sha256ForString:countryCode] forKey:@"fb_country"];
    
    [Adjust addGlobalPartnerParameter:[IMEncryptUtils sha256ForString:[IMKeychainUUIDManager getOrCreateLoginUUID]] forKey:@"fb_external_id"];
    
    [Adjust addGlobalCallbackParameter:[[DMConfigReader sharedInstance] sdkVersion] ?: @"" forKey:@"sdk_version_name"];
        
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];//获取app版本信息

    NSString *short_build = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
    NSString *app_BundleId = [infoDictionary objectForKey:@"CFBundleIdentifier"];
    [Adjust adidWithCompletionHandler:^(NSString * _Nullable adid) {
        NSLog(@"adjustid----%@",adid);
        
        // Note: ThinkingSDK class method needs to be verified
        
        [TDAnalytics setSuperProperties:@{
            @"version":short_build,
            @"ditch_name":app_BundleId,
            @"adjust_id":adid
        }];
        
    }];
}

- (void)AdjustConfigInit {
    NSString *appToken = [[DMConfigReader sharedInstance] adjustConfig].app_token;
    if (!appToken || appToken.length == 0) {
        [IMLogUtils warning:IMLogTagAd format:@"[Adjust] App Token 未配置，跳过初始化"];
        return;
    }
    [self configureWithAppToken:appToken];
}

- (BOOL)isAdjustInitialized {
    return _isInitialized;
}

#pragma mark - Attribution Callbacks

- (void)setAttributionCallback:(void(^)(BOOL isSuccess))callback {
    _attributionCallback = callback;
    
    // 启动超时定时器
    [self startAttributionTimeoutTimer];
    
    [IMLogUtils info:IMLogTagAd format:@"[Adjust] Attribution callback set with %0.1f seconds timeout", kAttributionTimeoutInterval];
}

- (void)startAttributionTimeoutTimer {
    [self stopAttributionTimeoutTimer];
    
    _attributionTimeoutTimer = [NSTimer scheduledTimerWithTimeInterval:kAttributionTimeoutInterval
                                                                target:self
                                                              selector:@selector(attributionTimeoutHandler)
                                                              userInfo:nil
                                                               repeats:NO];
}

- (void)stopAttributionTimeoutTimer {
    if (_attributionTimeoutTimer) {
        [_attributionTimeoutTimer invalidate];
        _attributionTimeoutTimer = nil;
    }
}

- (void)attributionTimeoutHandler {
    [IMLogUtils warning:IMLogTagAd format:@"[Adjust] Attribution callback timeout after %0.1f seconds", kAttributionTimeoutInterval];
    
    if (_attributionCallback) {
        _attributionCallback(NO);
        _attributionCallback = nil;
    }
    
    // 兼容旧回调
    if (_adjustCallBackBlcok) {
        _adjustCallBackBlcok(NO);
    }
    
    // 通知代理
    if (_delegate && [_delegate respondsToSelector:@selector(onAdjustCallBack:)]) {
        [_delegate onAdjustCallBack:NO];
    }
}

- (void)adjustAttributionChanged:(ADJAttribution *)attribution {
    [IMLogUtils info:IMLogTagAd format:@"[Adjust] Attribution changed: %@", attribution];
    
    // 停止超时定时器
    [self stopAttributionTimeoutTimer];
    
    // 更新当前归因信息
    _currentAttribution = [[DMAdjustAttributionInfo alloc] initWithADJAttribution:attribution];
    
    // 更新兼容属性 - 直接存储到内部变量
    if (attribution.campaign) {
        _adjustCampaign = attribution.campaign;
    }
    if (attribution.creative) {
        _adjustCreative = attribution.creative;
    }
    
    // 执行新回调
    if (_attributionCallback) {
        _attributionCallback(YES);
        _attributionCallback = nil;
    }
    
    // 兼容旧回调
    if (_adjustCallBackBlcok) {
        _adjustCallBackBlcok(YES);
    }
    
    // 通知代理
    if (_delegate) {
        if ([_delegate respondsToSelector:@selector(onAdjustCallBack:)]) {
            [_delegate onAdjustCallBack:YES];
        }
        if ([_delegate respondsToSelector:@selector(onAdjustAttributionChanged:)]) {
            [_delegate onAdjustAttributionChanged:_currentAttribution];
        }
    }
}


#pragma mark - Event Tracking

- (void)trackAdjustEvent:(NSString *)eventToken {
    [self trackAdjustEvent:eventToken withParameters:nil];
}

- (void)trackAdjustEvent:(NSString *)eventToken completion:(nullable void(^)(BOOL success, NSString * _Nullable errorMessage))completion {
    if (!_isInitialized) {
        NSString *errorMsg = @"Adjust not initialized";
        [IMLogUtils error:IMLogTagAd format:@"[Adjust] Cannot track event: %@", errorMsg];
        if (completion) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(NO, errorMsg);
            });
        }
        return;
    }
    
    if (!eventToken || eventToken.length == 0) {
        NSString *errorMsg = @"Event token is required";
        [IMLogUtils error:IMLogTagAd format:@"[Adjust] %@", errorMsg];
        if (completion) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(NO, errorMsg);
            });
        }
        return;
    }
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        ADJEvent *event = [[ADJEvent alloc] initWithEventToken:eventToken];
        [Adjust trackEvent:event];
        
        [IMLogUtils info:IMLogTagAd format:@"[Adjust] Event tracked asynchronously: %@", eventToken];
        
        if (completion) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(YES, nil);
            });
        }
    });
}

- (void)trackAdjustEvent:(NSString *)eventToken withParameters:(NSDictionary *)parameters {
    if (!_isInitialized) {
        [IMLogUtils error:IMLogTagAd format:@"[Adjust] Cannot track event, Adjust not initialized"];
        return;
    }
    
    if (!eventToken || eventToken.length == 0) {
        [IMLogUtils error:IMLogTagAd format:@"[Adjust] Event token is required"];
        return;
    }
    
    ADJEvent *event = [[ADJEvent alloc] initWithEventToken:eventToken];
    
    // 添加参数
    if (parameters && parameters.count > 0) {
        for (NSString *key in parameters) {
            NSString *value = [NSString stringWithFormat:@"%@", parameters[key]];
            [event addPartnerParameter:key value:value];
        }
    }
    
    [Adjust trackEvent:event];
    
    [IMLogUtils info:IMLogTagAd format:@"[Adjust] Event tracked: %@ with parameters: %@", eventToken, parameters];
}

- (void)adjustEvent:(ADJEvent *)event {
    [IMLogUtils warning:IMLogTagAd format:@"[Adjust] adjustEvent with ADJEvent is deprecated, use trackAdjustEvent: instead"];
    [Adjust trackEvent:event];
}

- (void)adjustCustomEventWithCustomId:(NSString *)cid {
    [IMLogUtils warning:IMLogTagAd format:@"[Adjust] adjustCustomEventWithCustomId is deprecated, use trackAdjustEvent: instead"];
    if (cid.length > 0) {
        NSString *eventToken = [[DMConfigReader sharedInstance]adjustConfig].app_token;
        NSDictionary *parameters = @{@"custom_id": cid};
        [self trackAdjustEvent:eventToken withParameters:parameters];
    }
}

#pragma mark - Attribution Info Getters

- (NSString *)getUserPropertyCampaign {
    if (_currentAttribution && _currentAttribution.campaign) {
        return _currentAttribution.campaign;
    }
    return _adjustCampaign; // 兼容旧属性
}

- (NSString *)getUserPropertyCreative {
    if (_currentAttribution && _currentAttribution.creative) {
        // 智能截取创意名称，最多20个字符
        NSString *creative = _currentAttribution.creative;
        if (creative.length > 20) {
            creative = [creative substringToIndex:20];
        }
        return creative;
    }
    return _adjustCreative; // 兼容旧属性
}

- (DMAdjustAttributionInfo *)getCurrentAttribution {
    return _currentAttribution;
}

#pragma mark - Event Tracking Callbacks

- (void)adjustEventTrackingSucceeded:(nullable ADJEventSuccess *)eventSuccessResponse {
    [IMLogUtils info:IMLogTagAd format:@"[Adjust] Event tracking succeeded: %@", eventSuccessResponse];
}

- (void)adjustEventTrackingFailed:(nullable ADJEventFailure *)eventFailureResponse {
    [IMLogUtils error:IMLogTagAd format:@"[Adjust] Event tracking failed: %@", eventFailureResponse];
}

#pragma mark - Deprecated Properties Implementation

// 兼容旧属性的实现
- (void(^)(BOOL))adjustCallBackBlcok {
    return _adjustCallBackBlcok;
}

- (void)setAdjustCallBackBlcok:(void(^)(BOOL))adjustCallBackBlcok {
    _adjustCallBackBlcok = adjustCallBackBlcok;
}

- (NSString *)adjustCampaign {
    return _adjustCampaign;
}

- (void)setAdjustCampaign:(NSString *)adjustCampaign {
    _adjustCampaign = adjustCampaign;
}

- (NSString *)adjustCreative {
    return _adjustCreative;
}

- (void)setAdjustCreative:(NSString *)adjustCreative {
    _adjustCreative = adjustCreative;
}

#pragma mark - Dealloc

- (void)dealloc {
    [self stopAttributionTimeoutTimer];
    [IMLogUtils info:IMLogTagAd format:@"[Adjust] DMAdjustManager deallocated"];
}

@end
